package com.treasury.glasses.controller;

import com.treasury.glasses.Main;
import com.treasury.glasses.controller.helper.Maskable;
import com.treasury.glasses.domain.ActivityLog;
import com.treasury.glasses.domain.fields.ActivityType;
import com.treasury.glasses.domain.ProgramUser;
import com.treasury.glasses.service.SettingsService;
import java.io.IOException;
import java.net.URL;
import java.util.Date;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;

/**
 * Controller or BackEnd for the FrontEnd Settings mask. Handles the mask
 * functionality and program states.
 * @author <a href="mailto:glasses@audienz.eu">Jean-Luc Burot</a>
 */

public class SettingsController implements Initializable, Maskable {
    /**
     * Privately handled service class for this controller class.
     */
    private final SettingsService service;
    
    /**
     * Privately handled ProgramUser for the Personal tab.
     */
    private ProgramUser personal;
    
    /**
     * Link to the personalUsername marked control on the mask.
     */
    @FXML
    private TextField personalUsername;
    
    /**
     * Link to the personalPassword marked control on the mask.
     */
    @FXML
    private TextField personalPassword;
    
    /**
     * Link to the personalFirstName marked control on the mask.
     */
    @FXML
    private TextField personalFirstName;
    
    /**
     * Link to the personalLastName marked control on the mask.
     */
    @FXML
    private TextField personalLastName;
    
    /**
     * Controller for the Settings mask.
     */
    public SettingsController() {
        this.service = new SettingsService();
    }
    
    /**
     * Takes the ActionEvent of the save Button on the mask.
     * @param event ActionEvent
     */
    @FXML
    private void saveButtonAction(final ActionEvent event) {
        try {
            save();
        } catch (IOException ex) {
            // TODO
            Logger.getLogger(SettingsController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    /**
     * Takes the ActionEvent of the cancel Button on the mask.
     * @param event ActionEvent
     */
    @FXML
    private void cancelButtonAction(final ActionEvent event) {
        try {
            close();
        } catch (IOException ex) {
            // TODO
            Logger.getLogger(SettingsController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    /**
     * Checks the fields for changes and saves them if necessary.
     */
    private void save() throws IOException {
        // Save Personal.
        if (!this.personalFirstName.getText().equals(this.personal.getFirstName())
         || !this.personalLastName.getText().equals(this.personal.getLastName())
         || !this.personalUsername.getText().equals(this.personal.getUsername())
         || !this.personalPassword.getText().equals(this.personal.getPassword())) {
            
            // Transfer all the TextField informations into the 
            this.personal.setFirstName(this.personalFirstName.getText());
            this.personal.setLastName(this.personalLastName.getText());
            this.personal.setUsername(this.personalUsername.getText());
            this.personal.setPassword(this.personalPassword.getText());
            
            // Save the ProgramUser.
            this.service.saveProgramUser(personal);
            
            // Create an ActivityLog.
            createActivityLog(Main.getLoggedInUser(), ActivityType.USER_MODIFICATION);
        }
        
        close();
    }
    
    /**
     * Closes the mask.
     */
    private void close() throws IOException {
        Main.getSceneController().unloadSettings();
    }
    
    private void createActivityLog(ProgramUser programUser, ActivityType activityType) {
        // Create an ActivityLog.
        ActivityLog activityLog = new ActivityLog();
        activityLog.setCreation(new Date());
        activityLog.setActivityType(activityType);
        activityLog.setProgramUser(programUser);
        System.out.println("activityType: " + activityType);
        System.out.println("activityLog: " + activityLog);

        // Persist the ActivityLog.
        this.service.createActivityLog(activityLog);
    }
    
    @Override
    public String getName() {
        return "Settings";
    }
    
    @Override
    public final void initialize(final URL url, final ResourceBundle rb) {
        // Set text limiter to the TextFields.
        Main.addTextLimiter(personalUsername, Main.TEXTFIELD_MAXLENGTH);
        Main.addTextLimiter(personalPassword, Main.TEXTFIELD_MAXLENGTH);
        Main.addTextLimiter(personalFirstName, Main.TEXTFIELD_MAXLENGTH);
        Main.addTextLimiter(personalLastName, Main.TEXTFIELD_MAXLENGTH);
        
        // Initialize the Personal tab.
        this.personal = Main.getLoggedInUser();
        this.personalFirstName.setText(this.personal.getFirstName());
        this.personalLastName.setText(this.personal.getLastName());
        this.personalUsername.setText(this.personal.getUsername());
        this.personalPassword.setText(this.personal.getPassword());
    }
}
